﻿namespace OutLook.Module.Infrastructure.Interfaces
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using OutLook.Model.Infrastructure;

    /// <summary>
    /// Interface of repository pattern
    /// </summary>
    public interface IRepository: IDisposable
    {
        /// <summary>
        /// Name of connected storage
        /// </summary>
        string GetStorageName<T>() where T : class;

        /// <summary>
        /// Indicates that storage are initialize
        /// </summary>
        bool IsInitialized<T>() where T : class;

        /// <summary>
        /// Initializes an new instance of Storage
        /// </summary>
        /// <param name="tableName"></param>
        void Initialize<T>(string connectionString) where T : class;

        /// <summary>
        /// Adds new entity to the storage
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Add<T>(T tableEntity) where T : class;

        /// <summary>
        /// Updates some enyity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Update<T>(T tableEntity) where T : class;

        /// <summary>
        /// Deletes entity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Delete<T>(T tableEntity) where T : class;

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IQueryable<T> GetQuery<T>() where T : class;

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IEnumerable<T> Enumerate<T>() where T : class;  
    }
}
